// 
//  Copyright (C) 2009 Vadim Ushakov
//  
//  This library is free software; you can redistribute it and/or modify it
//  under the terms of the GNU Lesser General Public License as published by
//  the Free Software Foundation; either version 2.1 of the License, or (at
//  your option) any later version.
//
//  This library is distributed in the hope that it will be useful, but
//  WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser
//  General Public License for more details.
//
//  You should have received a copy of the GNU Lesser General Public License
//  along with this library; if not, write to the Free Software Foundation,
//  Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
//  memcpy.c
//


#include <string.h>
#include <errno.h>

void *memcpy(void *dest, const void *src, size_t bytes)
{
	if ((src == NULL) || (dest == NULL))
	{
		errno = ERR_NULLPARAMETER;
		return (NULL);
	}

	#define Q sizeof(unsigned)

	char* d = (char*)dest;
	char* s = (char*)src;

	while (bytes > 0 && ((unsigned)d) % (Q * 2) != 0)
		*(d++) = *(s++), bytes--;

	size_t q = bytes / (Q * 2);
	bytes -= q * (Q * 2);
	while (q)
	{
		unsigned u1 = *(unsigned*)(s);
		unsigned u2 = *(unsigned*)(s + Q);
		*(unsigned*)(d    ) = u1;
		*(unsigned*)(d + Q) = u2;
		s += Q * 2;
		d += Q * 2;
		q--;
	}

	while (bytes > 0)
		*(d++) = *(s++), bytes--;

	return (dest);
}
